package org.NooLab.structures.texx.plugg.algo.intf;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;

import org.NooLab.utilities.net.GUID;




abstract public class AlgoReaderAbstract implements AlgoReaderIntf{

	private static final long serialVersionUID = 2971433693993395455L;

	int typeInfo = AlgorithmIntf._ALGOTYPE_READER ; // <<<<<<<<<<<<<<<<<< needs to adjusted for new types !!
	 
	String instanceGuid = "";
	// ....................................................

	protected DataDescription dataDescription;
	
	protected ArrayList<ArrayList<Double>> valueTable = new ArrayList<ArrayList<Double>>();
	protected ArrayList<Double> values ;
	protected ArrayList<String> stringvalues ;
	
	protected ArrayList<Double> outvalues = new ArrayList<Double>() ;
	protected ArrayList<String> outstringvalues = new ArrayList<String>() ;
	
	protected boolean isStrData ;
	
	protected AlgoSourceDescription sourceDescription ;
	
	protected int rangeViolationHandlingMode = AlgorithmIntf._ALGO_RANGEVIOLATION_AUTOCORRECT ;
	protected int rangeViolationCounter=0;
	
	protected boolean hasParameters = false; // will be true in case of algorithms like NumValEnum
	
	protected AlgorithmParameters parameters ; 
	
	protected String autoDescription = "" ;

	protected int inputColumnsCount = 1;

	private String inputSourceUrl;

	private Object sourceType;
	
	// ------------------------------------------------------------------------
	public AlgoReaderAbstract(){
		parameters = new AlgorithmParameters( this) ;
		instanceGuid = GUID.randomvalue() ;
	}
	// ------------------------------------------------------------------------
	
	@Override
	public int getType() {
		return typeInfo;
	}
	

	@Override
	public String getInstanceGuid() {
		return instanceGuid;
	}

	
	abstract public String getDescription() ;
	
	public int getInputColumnsCount(){
		return inputColumnsCount;
	}
	public void setInputColumnsCount( int icc){
		inputColumnsCount = icc;
	}
	
	
	protected boolean setCalculationResultValue(int index, double value) {
		boolean rB=true;
		
		if (index < outvalues.size()) {
			outvalues.set(index , value);
		} else {
			outvalues.add(value);
		}
		
		return rB;
	}
	

	@Override
	public void clear() {
		valueTable.clear();
	}
	
	@Override
	public String getDocTypeMime(){
		// "mime :: AlgoReaderAbstract :: n.i.y. ";
		String mimeValue="";

		// ...
		return mimeValue;
	}
	
	public void setValueTableColumn( int index, ArrayList<?> inValueCol ) {

		valueTable.set(index, (ArrayList<Double>) inValueCol) ;
	}
	

	 
	
	abstract public int calculate() throws Exception ;
	
	abstract public boolean performPostProcessing();

	abstract public String getText();
	
	
	
	public int setInputData( ByteArrayInputStream inValues ){
	
		return 0;
	}

	public void setInputSource( String urlString, int sourcetype ){
		
		inputSourceUrl = urlString;
		sourceType = sourcetype;
		
	}
	
		

	
	
	public ArrayList<Double> _getTransformedValues() {
		 
		return outvalues;
	}
 

	/**
	 * @return the hasParameters
	 */
	public boolean hasParameters() {
		return hasParameters;
	}


	@Override
	public AlgorithmParameters getParameters() {
		return parameters;
	}
	
 
	@Override
	public void setParameters(ArrayList<Object> params)  throws Exception{
		 
		basicParametersAssimilation(params) ;
	}
	
	
	@Override
	public void setParameters(AlgorithmParameters algorithmparams)  throws Exception{
		
		if (parametersNullCheck(algorithmparams)==false) return;
		basicParametersAssimilation(algorithmparams) ;
		
		Class clzz = getClass().getMethod("setParameters").getDeclaringClass();
		if (clzz != this.getClass()){
			// of which interface?   C:\Programs\dev\eclipse\xlibs\reflection
			Class[] intfaces = clzz.getInterfaces() ;
			
		}

	}

	
	
	protected boolean parametersNullCheck(AlgorithmParameters algorithmparams){
		boolean rB=true;
		
		if (algorithmparams==null){
			rB=false;
		}
		if ((algorithmparams.items==null) || (algorithmparams.items.size()==0)){
			rB=false;
		}
		return rB;
	}

	protected void basicParametersAssimilation(AlgorithmParameters algorithmParams){
		
		AlgorithmParametersHelper paramsHelper = new AlgorithmParametersHelper ();
		
		parameters = paramsHelper.assimilate(this, algorithmParams);
	}
	
	protected void basicParametersAssimilation( ArrayList<Object> params ){
		
		AlgorithmParametersHelper paramsHelper = new AlgorithmParametersHelper ();
		
		parameters = paramsHelper.assimilateOpenObjectList(this, params);
		
	}
	 
	
	
	public String[] showAvailableParameters() {
		String[] paramsDescription = new String[0];
		return paramsDescription;
	}	
	

	public int getRangeViolationCounter() {
		return rangeViolationCounter;
	}

	public void setRangeViolationCounter(int rvCounter) {
		this.rangeViolationCounter = rvCounter;
	}
	
}
